package ks.server.persist;

import java.util.Collection;

import ks.managers.user.User;
import ks.managers.user.UserManager;

/**
 * Persistently manages all known users.
 * 
 * @author Christopher Page
 */
public class PersistentUserManager extends UserManager {
	
	/**
	 * Protect access to this constructor.
	 */
	public PersistentUserManager() {
		super();
		
		initialize();
	}

	/**
	 * Get users from database and populate knownUsers.
	 */
	private void initialize() {
		try {
			Collection<User> users = Database.getUsers();
			for (User u : users) {
				knownUsers.put(u.name, u);
			}
		} catch (Exception e) {
			System.err.println("Unable to populate from db");
		}
	}

	/**
	 * Add user to the store of users.
	 * 
	 * @param u The User to add to the store of users.
	 * @return true on success.
	 */
	public boolean addUser (User u) {
		try {
			if (!Database.addUser(u)) {
				System.err.println("Unable to add User to persistent database: User already exists.");
				return false;
			}
			
			super.addUser(u);
		} catch (Exception e1) {
			System.err.println("Unable to add user to persistent database: " + u.getName() + ". " + e1.getMessage());
			return false;
		}
		
		return true;
	}

	/**
	 * Remove user from the store of users.
	 * 
	 * @param u The User to remove from the store of users.
	 * @return true on success. false on failure.
	 */
	public boolean removeUser (User u) {
		try {
			if (!Database.deleteUser(u.getName())) {
				System.err.println("Unable to remove user from persistent database.");
				return false;
			}
			
			super.removeUser(u);
		} catch (Exception e1) {
			System.err.println("Unable to remove user from persistent database: " + u.getName());
			return false;
		}
		
		return true;
	}
	
	/**
	 * Prevent removal of all users.
	 * 
	 * @return false always.
	 */
	public boolean removeAllUsers () {
		return false;
	}
	
	/**
	 * Call whenever a user's data is changed in order to synchronize the data
	 * in the User class instance with that of the database.
	 * 
	 * @param username The username of the User class that was updated.
	 * @return true on success. false on failure.
	 */
	public boolean updateUser (String username) {
		try {
			if (!Database.updateUser(super.getUser(username))) {
				System.err.println("Unable to update user: " + username);
				return false;
			}
		} catch (Exception e) {
			System.err.println("Unable to update user in persistent database: " + username);
			return false;
		}
		
		return true;
	}
}